<!DOCTYPE html>

<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">

<title>MAKEROBOT - TJPlurker API Documentation</title>

<link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "./";
</script>

<script type="text/javascript" charset="utf-8" src="./js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="./js/navigation.js"></script>
<script type="text/javascript" charset="utf-8" src="./js/search_index.js"></script>
<script type="text/javascript" charset="utf-8" src="./js/search.js"></script>
<script type="text/javascript" charset="utf-8" src="./js/searcher.js"></script>
<script type="text/javascript" charset="utf-8" src="./js/darkfish.js"></script>


<body class="file">
<nav id="metadata">
  <nav id="home-section" class="section">
  <h3 class="section-header">
    <a href="./index.html">Home</a>
    <a href="./table_of_contents.html#classes">Classes</a>
    <a href="./table_of_contents.html#methods">Methods</a>
  </h3>
</nav>


  <nav id="search-section" class="section project-section" class="initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <h3 class="section-header">
      <input type="text" name="search" placeholder="Search" id="search-field"
             title="Type to search, Up and Down to navigate, Enter to load">
    </h3>
  </form>

  <ul id="search-results" class="initially-hidden"></ul>
</nav>


  <div id="project-metadata">
    <nav id="fileindex-section" class="section project-section">
  <h3 class="section-header">Pages</h3>

  <ul>
  
    <li class="file"><a href="./GETSTART.html">GETSTART</a>
  
    <li class="file"><a href="./MAKEROBOT.html">MAKEROBOT</a>
  
    <li class="file"><a href="./README.html">README</a>
  
  </ul>
</nav>

    <nav id="classindex-section" class="section project-section">
  <h3 class="section-header">Class and Module Index</h3>

  <ul class="link-list">
  
    <li><a href="./Legacy.html">Legacy</a>
  
    <li><a href="./Legacy/TJPlurker.html">Legacy::TJPlurker</a>
  
    <li><a href="./Legacy/TJPlurker/NotificationData.html">Legacy::TJPlurker::NotificationData</a>
  
    <li><a href="./Legacy/TJPlurker/Robot.html">Legacy::TJPlurker::Robot</a>
  
    <li><a href="./Legacy/TJPlurker/Service.html">Legacy::TJPlurker::Service</a>
  
    <li><a href="./Legacy/TJPlurker/ThreadService.html">Legacy::TJPlurker::ThreadService</a>
  
    <li><a href="./TJP.html">TJP</a>
  
    <li><a href="./TJP/NotificationData.html">TJP::NotificationData</a>
  
    <li><a href="./TJP/Robot.html">TJP::Robot</a>
  
    <li><a href="./TJP/Service.html">TJP::Service</a>
  
    <li><a href="./TJP/TJPlurker.html">TJP::TJPlurker</a>
  
    <li><a href="./TJP/ThreadService.html">TJP::ThreadService</a>
  
  </ul>
</nav>

  </div>
</nav>

<div id="documentation" class="description">
  
<h1 id="label-%E6%89%93%E9%80%A0%E5%99%97%E6%B5%AA%E6%A9%9F%E5%99%A8%E4%BA%BA">打造噗浪機器人</h1>

<p>瀏覽這一頁之前，建議先看過 <a href="GETSTART.html">豈不走</a></p>

<p>這一頁展示各種利用 TJPlurker 製作機器人的技巧，是筆者製作機器人的技巧紀錄，僅供參考。</p>

<h2 id="label-%E5%9F%BA%E6%9C%AC%E6%9E%B6%E6%A7%8B">基本架構</h2>

<p>所有機器人的製作遵循以下步驟：</p>
<ol><li>
<p>初始化 <a href="TJP/Robot.html">TJP::Robot</a> 物件</p>
</li><li>
<p>初始化 <a href="TJP/Service.html">TJP::Service</a> 物件</p>
</li><li>
<p>註冊 <a href="TJP/Service.html">TJP::Service</a> 到 Robot</p>
</li><li>
<p>啟動 Robot</p>
</li></ol>

<h3 id="label-%E5%88%A9%E7%94%A8%E7%B9%BC%E6%89%BF">利用繼承</h3>

<p>首先介紹的方法比較直觀，就是繼承自 <a href="TJP/Service.html">TJP::Service</a> ，並且 override
<a href="TJP/Service.html#method-i-serve">TJP::Service#serve</a>。</p>

<pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">'tjplurk'</span>
<span class="ruby-identifier">include</span> <span class="ruby-constant">TJP</span>
<span class="ruby-identifier">robot</span> = <span class="ruby-constant">Robot</span>.<span class="ruby-identifier">new</span>(<span class="ruby-constant">CONSUMER_KEY</span>, <span class="ruby-constant">CONSUMER_SECRET</span>, <span class="ruby-constant">ACCESS_TOKEN</span>, <span class="ruby-constant">ACCESS_TOKEN_SECRET</span>)

<span class="ruby-keyword">class</span> <span class="ruby-constant">MyService</span> <span class="ruby-operator">&lt;</span> <span class="ruby-constant">Service</span>
    <span class="ruby-keyword">def</span> <span class="ruby-identifier">serve</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
        <span class="ruby-comment"># 你的服務內容</span>
    <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>

<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">add_service</span>(<span class="ruby-constant">MyService</span>.<span class="ruby-identifier">new</span>)
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">start</span>
</pre>

<p>參數也可以是類別：</p>

<pre>robot.add_service(MyService)</pre>

<p>等同：</p>

<pre>robot.add_service(MyService.new)</pre>

<h4 id="label-%E5%B0%87%E6%A2%9D%E4%BB%B6%E5%88%86%E9%9B%A2">將條件分離</h4>

<p>寫機器人免不了判斷使用者輸入了什麼，然後再決定執行什麼，例如你要做一個只針對首PO，且文字內容有“哈哈”的噗做出“Haha”的回應，可以這麼寫：</p>

<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">MyService</span> <span class="ruby-operator">&lt;</span> <span class="ruby-constant">TJP</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>
    <span class="ruby-keyword">def</span> <span class="ruby-identifier">serve</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
        <span class="ruby-keyword">if</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-string">&quot;new_plurk&quot;</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">content</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp">%r哈哈/</span>
            <span class="ruby-identifier">tjp</span>.<span class="ruby-identifier">response_add</span>(<span class="ruby-string">&quot;Haha&quot;</span>)
        <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>

<p>或者你可以複寫 <a href="TJP/Service.html#method-i-decide">TJP::Service#decide</a>
，作為判斷之用，如果最後回傳的為true（neither nil nor false），那麼就該服務就會執行action</p>

<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">MyService</span> <span class="ruby-operator">&lt;</span> <span class="ruby-constant">TJPlurker</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>
    <span class="ruby-keyword">def</span> <span class="ruby-identifier">decide</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
        <span class="ruby-keyword">return</span> <span class="ruby-keyword">true</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-string">&quot;new_plurk&quot;</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">content</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp">%r哈哈/</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">def</span> <span class="ruby-identifier">action</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
        <span class="ruby-identifier">tjp</span>.<span class="ruby-identifier">response_add</span>(<span class="ruby-string">&quot;Haha&quot;</span>)
    <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>

<h3 id="label-%E5%88%A9%E7%94%A8Block">利用Block</h3>

<p>Ruby有個最強大的特色就是Block，也可以利用它來製作機器人</p>

<pre class="ruby"><span class="ruby-identifier">require</span> <span class="ruby-string">'tjplurker'</span>
<span class="ruby-identifier">include</span> <span class="ruby-constant">TJP</span>
<span class="ruby-identifier">robot</span> = <span class="ruby-constant">Robot</span>.<span class="ruby-identifier">new</span>(<span class="ruby-constant">CONSUMER_KEY</span>, <span class="ruby-constant">CONSUMER_SECRET</span>, <span class="ruby-constant">ACCESS_TOKEN</span>, <span class="ruby-constant">ACCESS_TOKEN_SECRET</span>)

<span class="ruby-identifier">your_service</span> = <span class="ruby-constant">Service</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
    <span class="ruby-comment"># 你的服務內容</span>
}

<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">add_service</span>(<span class="ruby-identifier">your_service</span>)
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">start</span>
</pre>

<h2 id="label-%E9%80%B2%E9%9A%8E%E6%9E%B6%E6%A7%8B">進階架構</h2>

<p>如果你要製作的是多功能的機器人，這裡提供一些參考。</p>

<h3 id="label-%E4%BB%A5%E7%89%A9%E4%BB%B6">以物件</h3>

<p>將Service物件包在module裡面。</p>

<pre class="ruby"><span class="ruby-keyword">module</span> <span class="ruby-constant">Services</span>
    <span class="ruby-identifier">@@service_a</span> = <span class="ruby-constant">Service</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span> }
    <span class="ruby-identifier">@@service_b</span> = <span class="ruby-constant">Service</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span> }
    <span class="ruby-identifier">@@service_c</span> = <span class="ruby-constant">Service</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span> }
<span class="ruby-keyword">end</span>

<span class="ruby-constant">Services</span>.<span class="ruby-identifier">class_variables</span>.<span class="ruby-identifier">each</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">var</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">robot</span>.<span class="ruby-identifier">add_service</span>(<span class="ruby-constant">Services</span>.<span class="ruby-identifier">class_variable_get</span>(<span class="ruby-identifier">var</span>))
}
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">start</span>
</pre>

<h3 id="label-%E4%BB%A5%E9%A1%9E%E5%88%A5">以類別</h3>

<p>這個方法是用繼承和overriding達到一樣的效果，優點是個別服務可以有自己的成員、方法，適合比較複雜的服務，建議分成兩個檔案分離服務與機器人。</p>

<pre class="ruby"><span class="ruby-keyword">module</span> <span class="ruby-constant">Services</span>
    <span class="ruby-keyword">class</span> <span class="ruby-constant">S1</span> <span class="ruby-operator">&lt;</span> <span class="ruby-constant">TJPlurker</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>
        <span class="ruby-keyword">def</span> <span class="ruby-identifier">serve</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
        <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">class</span> <span class="ruby-constant">S2</span> <span class="ruby-operator">&lt;</span> <span class="ruby-constant">TJPlurker</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>
        <span class="ruby-keyword">def</span> <span class="ruby-identifier">serve</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
        <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">class</span> <span class="ruby-constant">S3</span> <span class="ruby-operator">&lt;</span> <span class="ruby-constant">TJPlurker</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>
        <span class="ruby-keyword">def</span> <span class="ruby-identifier">serve</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
        <span class="ruby-keyword">end</span>
    <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>

<span class="ruby-identifier">include</span> <span class="ruby-constant">Services</span>
<span class="ruby-constant">Services</span>.<span class="ruby-identifier">constants</span>.<span class="ruby-identifier">each</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">const</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">robot</span>.<span class="ruby-identifier">add_service</span>(<span class="ruby-constant">Services</span>.<span class="ruby-identifier">const_get</span>(<span class="ruby-identifier">const</span>))
}
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">start</span>
</pre>

<h2 id="label-%E6%9C%80%E7%B0%A1%E5%96%AE%E7%9A%84%E6%A9%9F%E5%99%A8%E4%BA%BA">最簡單的機器人</h2>

<p>如果建構Service物件的時候不加任何參數，預設的服務是把所有在河道上聽到的東西印出來。</p>

<pre>robot.add_service(TJP::Service.new)
robot.start</pre>

<p>這和以下的程式碼意義相同。</p>

<pre class="ruby"><span class="ruby-identifier">serv</span> = <span class="ruby-constant">TJP</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">p</span> <span class="ruby-identifier">data</span>
}
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">add_service</span>(<span class="ruby-identifier">serv</span>)
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">start</span>
</pre>

<h2 id="label-%E5%83%85%E9%87%9D%E5%B0%8D%E6%96%B0%E5%99%97%2F%E5%9B%9E%E6%87%89">僅針對新噗/回應</h2>

<p>有時候機器人只會針對新的噗有效（例如掰噗），有些則是可以在噗的回應中與使用者互動（例如每少女噗工廠的堆疊），這邊示範怎麼針對新噗或者回應做出相對應的服務。</p>

<pre class="ruby"><span class="ruby-identifier">service_echo</span> = <span class="ruby-constant">TJP</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjplurker</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
    <span class="ruby-keyword">if</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-string">&quot;new_plurk&quot;</span>
        <span class="ruby-identifier">tjplurker</span>.<span class="ruby-identifier">response_add</span>(<span class="ruby-identifier">data</span>.<span class="ruby-identifier">plurk_id</span>, <span class="ruby-string">&quot;I heard a new Plurk.&quot;</span>)
    <span class="ruby-keyword">else</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">type</span> <span class="ruby-operator">==</span> <span class="ruby-string">&quot;new_response&quot;</span>
        <span class="ruby-identifier">tjplurker</span>.<span class="ruby-identifier">response_add</span>(<span class="ruby-identifier">data</span>.<span class="ruby-identifier">plurk_id</span>, <span class="ruby-string">&quot;I heard a new Response.&quot;</span>)
    <span class="ruby-keyword">end</span>
}
</pre>

<h2 id="label-%E5%9B%9E%E8%A9%B1%E5%8A%9F%E8%83%BD">回話功能</h2>

<p>如何作到掰噗和卡馬警衛的功能？這裡提供一個解，利用正規表達式去比對內容，決定要回什麼話，當然，簡單的作法是直接寫在程式碼中，否則使用資料庫會更合適。</p>

<pre class="ruby"><span class="ruby-identifier">service_response</span> = <span class="ruby-constant">TJP</span><span class="ruby-operator">::</span><span class="ruby-constant">Service</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjplurker</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">answer</span> = <span class="ruby-string">&quot;&quot;</span>
    <span class="ruby-keyword">case</span> <span class="ruby-identifier">data</span>.<span class="ruby-identifier">content</span>
        <span class="ruby-keyword">when</span> <span class="ruby-regexp">%r早安/</span>
            <span class="ruby-identifier">answer</span> = <span class="ruby-string">&quot;早安啊～&quot;</span>
        <span class="ruby-keyword">when</span> <span class="ruby-regexp">%r晚安/</span>
            <span class="ruby-identifier">answer</span> = <span class="ruby-string">&quot;晚安，祝你有個好夢^^&quot;</span>
        <span class="ruby-keyword">when</span> <span class="ruby-regexp">%r作業/</span>
            <span class="ruby-identifier">answer</span> = <span class="ruby-string">&quot;喔不，作業……&quot;</span>
    <span class="ruby-keyword">end</span>
    <span class="ruby-identifier">tjplurker</span>.<span class="ruby-identifier">response_add</span>(<span class="ruby-identifier">data</span>.<span class="ruby-identifier">plurk_id</span>, <span class="ruby-identifier">answer</span>)
}
</pre>

<p>如果想要有人使用回應功能指定對象時（例如@tonytonyjan:）才會回應（例如卡馬警衛就是用這個方法）。並不能這樣寫：</p>

<pre>case data.content
    when /@tonytonyjan/
        tjp.response_add(data.plurk.id, &quot;Are you calling me?&quot;)
end</pre>

<p>因為這類的訊息，使用Plurk API所監聽到的內容會長這樣：</p>

<pre class="ruby"><span class="ruby-operator">&lt;</span><span class="ruby-identifier">a</span> <span class="ruby-identifier">href</span>=<span class="ruby-string">&quot;http://www.plurk.com/tonytonyjan&quot;</span> <span class="ruby-keyword">class</span>=<span class="ruby-string">&quot;ex_link&quot;</span><span class="ruby-operator">&gt;</span><span class="ruby-identifier">tonytonyjan</span><span class="ruby-operator">&lt;</span><span class="ruby-regexp">%ra&gt;:
</span></pre>

<p>Plurk是用網址來判斷的，所以只要將程式碼改成如下即可運作：</p>

<pre>case data.content
    when /http:\/\/www.plurk.com\/tonytonyjan/
        tjp.response_add(data.plurk.id, &quot;Are you calling me?&quot;)
end</pre>

<h2 id="label-%E8%A8%98%E6%86%B6%2F%E5%A0%86%E7%96%8A">記憶/堆疊</h2>

<p>有時候你會希望使用者發噗觸發條件的時候，在該噗之後的回應裡，機器人都能與使用者互動，就像美少女噗工廠中堆疊的概念一樣，然後過一段時間之後，堆疊就會消失。類似應用可以用來製作猜數字、撿石頭、純聊天等功能，當然，設計大如美少女噗工廠的角色扮演遊戲也不是不可能。</p>

<p>使用方式和TJP::Service很像</p>

<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">YourService</span> <span class="ruby-operator">&lt;</span> <span class="ruby-constant">TJP</span><span class="ruby-operator">::</span><span class="ruby-constant">ThreadService</span>
    <span class="ruby-keyword">def</span> <span class="ruby-identifier">decide</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-keyword">def</span> <span class="ruby-identifier">action</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
    <span class="ruby-keyword">end</span>

    <span class="ruby-keyword">def</span> <span class="ruby-identifier">final</span> <span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span>
    <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>

<p>TJP::ThreadService繼承自TJPlurker::Service，不同的地方在於：</p>
<ul><li>
<p><a href="TJP/Service.html#method-i-decide">TJP::Service#decide</a>
只做用在首PO（data.type==“new_plurk”），如果回傳true，會產生一個Thread，在一定的時間內記得這這個討論串</p>
</li><li>
<p><a href="TJP/Service.html#method-i-action">TJP::Service#action</a>
只作用在回覆（data.type==“new_response”），但不會作用在沒有通過decide的噗裡面</p>
</li><li>
<p><a
href="TJP/ThreadService.html#method-i-final">TJP::ThreadService#final</a>
會在Thread關閉之後執行，你可以透過此告知使用者功能已經關閉了</p>
</li></ul>

<p>如果不用類別的話，也可以這樣寫。</p>

<pre class="ruby"><span class="ruby-identifier">service</span> = <span class="ruby-constant">TJPlurker</span><span class="ruby-operator">::</span><span class="ruby-constant">ThreadService</span>.<span class="ruby-identifier">new</span>{<span class="ruby-operator">|</span><span class="ruby-identifier">tjp</span>, <span class="ruby-identifier">data</span><span class="ruby-operator">|</span>
    <span class="ruby-identifier">tjp</span>.<span class="ruby-identifier">response_add</span>(<span class="ruby-identifier">data</span>.<span class="ruby-identifier">plurk_id</span>, <span class="ruby-identifier">data</span>.<span class="ruby-identifier">content</span>)
}
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">add_service</span>(<span class="ruby-identifier">service</span>)
<span class="ruby-identifier">robot</span>.<span class="ruby-identifier">start</span>
</pre>

<p>預設下， <a href="TJP/Service.html#method-i-decide">TJP::Service#decide</a>
是true， <a
href="TJP/ThreadService.html#method-i-final">TJP::ThreadService#final</a>
則是什麼都不做。</p>

</div>



<footer id="validator-badges">
  <p><a href="http://validator.w3.org/check/referer">[Validate]</a>
  <p>Generated by <a href="https://github.com/rdoc/rdoc">RDoc</a> 3.12.
  <p>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish Rdoc Generator</a> 3.
</footer>

